package viper.diversity;


public class Dediversity {
	private static byte [] A;
	private static byte [] B;
	private static byte [] C;
	private static byte [] A_Xor_B;
	private static byte [] A_Xor_C;
	private static byte [] B_Xor_C;
	private static byte [][] Two_Three_x = new byte[2][];
	private static byte [][] Four_Six_x;

	/** SHIT THAT'S WRONG WITH THIS CODE...
	 *  1. No case for when all packets have been received.
	 *  2. The partial decode case doesn't include all default cases (it should be able to partial decode IF needed but also be able to decode normally.
	 *  3. if/else if/else baskets short-circuit prematurely (i.e. if one and three are null, it'll still try to check the first case...)
	 *  4. Coding includes pkt type in header, which is already done by ViperHeader methods.
	 *  5. Initialization due to above has incorrect lengths.
	 *  6. Some variables are just never initialized.
	 *  7. Random minor syntax that causes null pointer errors.
	 **/
	
	public static byte[][] undiversify(byte [] one, byte [] two,byte [] three, boolean partial){
		if(!partial){
			if (one!=null && two!=null && three==null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
			}
			else if (one!=null && two==null && three!=null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				A_Xor_B= new byte[one.length];
				System.arraycopy(three,0,A_Xor_B,0,three.length);
				B = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(A[i]^A_Xor_B[i]);
				}	
			}
			else if (one==null && two!=null && three!=null){
				B= new byte[two.length];
				System.arraycopy(two,0,A_Xor_B,0,two.length);
				A_Xor_B= new byte[three.length];
				System.arraycopy(three,0,A_Xor_B,0,three.length);
				A = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(B[i]^A_Xor_B[i]);
				}
			}
			else if(one==null && two==null && three!=null){
				A = null;
				B = null;
			}
			else if(one==null && two!=null && three==null){
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
				A = null;
			}
			else if(one!=null && two==null && three==null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				B=null;
			}
			else{
				A = one;
				B = two;
			}
			Two_Three_x[0]=A;
			Two_Three_x[1]=B;
			return Two_Three_x;
		}
		else{
			if(one==null&&two==null){
				A= null;
				B=null;
			}
			else if(one==null && three==null){
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
				A = null;
			}
			else if(two==null && three ==null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				B=null;
			}	
			Two_Three_x[0]=A;
			Two_Three_x[1]=B;
			return Two_Three_x;
		}
	}
	public static byte [][] undiversify(byte [] one, byte [] two, byte [] three, byte [] four, byte [] five, byte [] six, boolean partial){
		boolean decodedA, decodedB, decodedC;
		decodedA = false;
		decodedB= false;
		decodedC = false;
		if(one!=null && two!=null && three!=null){
			A= new byte[one.length];
			System.arraycopy(one,0,A,0,one.length);
			B= new byte[one.length];
			System.arraycopy(two,0,B,0,one.length);
			C= new byte[one.length];
			System.arraycopy(three,0,C,0,one.length);
			Four_Six_x[0]=A;
			Four_Six_x[1]=B;
			Four_Six_x[2]=C;
			return Four_Six_x;
		}
		if(!partial){
			if(one==null && two ==null && three == null)
			{
				return null;
			}
			else if(one==null && two == null&&five!=null &&six!=null){
				C= new byte[three.length];
				System.arraycopy(three,0,C,0,three.length);
				A = new byte [three.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(C[i]^five[i]);
				}
				B = new byte [three.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(C[i]^six[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(one==null && two == null&&four!=null &&five!=null){
				C= new byte[three.length];
				System.arraycopy(three,0,C,0,three.length);
				A = new byte [three.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(C[i]^five[i]);
				}
				B = new byte [three.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(A[i]^four[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(one==null && two == null&&four!=null &&six!=null){
				C= new byte[three.length];
				System.arraycopy(three,0,C,0,three.length);
				B = new byte [three.length];			
				for (int i =0;i<B.length;i++)
				{
					B[i]=(byte)(C[i]^six[i]);
				}
				A = new byte [three.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(B[i]^four[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(one==null && three == null && four!=null && six!=null){
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
				A = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(B[i]^four[i]);
				}
				C = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					C[i]=(byte)(B[i]^six[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(one==null && three == null && four!=null && five!=null){
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
				A = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(B[i]^four[i]);
				}
				C = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					C[i]=(byte)(A[i]^five[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(one==null && three == null && five!=null && six!=null){
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
				C = new byte [two.length];			
				for (int i =0;i<C.length;i++)
				{
					C[i]=(byte)(B[i]^six[i]);
				}
				A = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(C[i]^five[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(two==null && three == null && four!=null && five !=null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				B = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(A[i]^four[i]);
				}
				C = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					C[i]=(byte)(A[i]^five[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(two==null && three == null && four!=null && six !=null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				B = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(A[i]^four[i]);
				}
				C = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					C[i]=(byte)(B[i]^six[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if(two==null && three == null && five!=null && six !=null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				C = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					C[i]=(byte)(A[i]^five[i]);
				}
				B = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(C[i]^six[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if (one==null && two !=null && three !=null && four!=null){
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
				C= new byte[two.length];
				System.arraycopy(three,0,C,0,two.length);
				A = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(B[i]^four[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if (one==null && two !=null && three!=null && five!=null){
				B= new byte[two.length];
				System.arraycopy(two,0,B,0,two.length);
				C= new byte[two.length];
				System.arraycopy(three,0,C,0,two.length);
				A = new byte [two.length];			
				for (int i =0;i<A.length;i++)
				{
					A[i]=(byte)(C[i]^five[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if (two==null && one !=null && three !=null && four !=null ){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				C= new byte[one.length];
				System.arraycopy(three,0,C,0,one.length);
				B = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(A[i]^four[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if (two==null && one !=null && three !=null && six !=null ){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				C= new byte[one.length];
				System.arraycopy(three,0,C,0,one.length);
				B = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					B[i]=(byte)(C[i]^six[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if (three==null && one != null && two !=null && five !=null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				B= new byte[one.length];
				System.arraycopy(two,0,B,0,one.length);
				C = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					C[i]=(byte)(A[i]^five[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else if (three==null && one != null && two !=null && six !=null){
				A= new byte[one.length];
				System.arraycopy(one,0,A,0,one.length);
				B= new byte[one.length];
				System.arraycopy(two,0,B,0,one.length);
				C = new byte [one.length];			
				for (int i =0;i<A.length;i++)
				{
					C[i]=(byte)(B[i]^six[i]);
				}
				Four_Six_x[0]=A;
				Four_Six_x[1]=B;
				Four_Six_x[2]=C;
				return Four_Six_x;
			}
			else{
				return null;
			}
		}
		else{
			if(one == null && two ==null && three ==null){
				Four_Six_x[0]=null;
				Four_Six_x[1]=null;
				Four_Six_x[2]=null;
				return Four_Six_x;
			}
			if (one !=null && two != null && three != null){
				Four_Six_x[0]=one;
				Four_Six_x[1]=two;
				Four_Six_x[2]=three;
				return Four_Six_x;
			}
			else if(one !=null && two !=null){
				Four_Six_x[0]=one;
				Four_Six_x[1]=two;
				if(five!=null){
					C = new byte [one.length];
					for (int i =0;i<C.length;i++)
					{
						C[i]=(byte)(one[i]^five[i]);
					}
					Four_Six_x[2]=C;
				}
				else if (six != null){
					C = new byte [one.length];
					for (int i =0;i<C.length;i++)
					{
						C[i]=(byte)(two[i]^six[i]);
					}
					Four_Six_x[2]=C;

				}
				else{
					Four_Six_x[2]=null;
				}
				return Four_Six_x;
			}
			else if(one !=null && three !=null){
				Four_Six_x[0]=one;
				Four_Six_x[2]=three;
				if(four!=null){
					B = new byte [one.length];
					for (int i =0;i<B.length;i++)
					{
						B[i]=(byte)(one[i]^four[i]);
					}
					Four_Six_x[1]=B;
				}
				else if (six != null){
					B = new byte [one.length];
					for (int i =0;i<B.length;i++)
					{
						B[i]=(byte)(three[i]^six[i]);
					}
					Four_Six_x[1]=B;

				}
				else{
					Four_Six_x[1]=null;
				}
				return Four_Six_x;
			}
			else if(three !=null && two !=null){
				Four_Six_x[2]=three;
				Four_Six_x[1]=two;
				if(five!=null){
					A = new byte [one.length];
					for (int i =0;i<A.length;i++)
					{
						A[i]=(byte)(three[i]^five[i]);
					}
					Four_Six_x[0]=A;
				}
				else if (four != null){
					A = new byte [one.length];
					for (int i =0;i<A.length;i++)
					{
						A[i]=(byte)(two[i]^four[i]);
					}
					Four_Six_x[0]=C;

				}
				else{
					Four_Six_x[0]=null;
				}
				return Four_Six_x;
			}
			else if (one !=null){
				Four_Six_x[0]=one;
				if(four != null){
					B = new byte [one.length];
					for (int i =0;i<B.length;i++)
					{
						B[i]=(byte)(one[i]^four[i]);
					}
					decodedB=true;
					Four_Six_x[1]=B;
					if (six != null){
						C = new byte [one.length];
						for (int i =0;i<B.length;i++)
						{
							C[i]=(byte)(B[i]^six[i]);
						}
						decodedC = true;
						Four_Six_x[2]=C;
					}
					else{
						Four_Six_x[2]=null;
					}
				}
				else{
					Four_Six_x[1]=null;
				}
				if(five != null){
					C = new byte [one.length];
					for (int i =0;i<C.length;i++)
					{
						C[i]=(byte)(one[i]^five[i]);
					}
					Four_Six_x[2]=C;
					if(six!=null){
						B = new byte [one.length];
						for (int i =0;i<B.length;i++)
						{
							B[i]=(byte)(C[i]^six[i]);
						}
						Four_Six_x[1]=B;
					}
					else{
						if(!decodedB)
							Four_Six_x[1]=null;
						else{}
					}
				}
				else{
					if(!decodedC)
						Four_Six_x[2]=null;
					else{}
				}

			}
			else if (two !=null){
				Four_Six_x[1]=one;
				if(four != null){
					A = new byte [two.length];
					for (int i =0;i<A.length;i++)
					{
						A[i]=(byte)(two[i]^four[i]);
					}
					decodedA = true;
					Four_Six_x[0]=A;
					if(five!=null){
						C = new byte [two.length];
						for (int i =0;i<C.length;i++)
						{
							C[i]=(byte)(A[i]^five[i]);
						}
						decodedC= true;
						Four_Six_x[2]=C;
					}
					else{
						Four_Six_x[2]=null;
					}

				}
				else{
					Four_Six_x[0]=null;
				}
				if(six != null){
					C = new byte [two.length];
					for (int i =0;i<C.length;i++)
					{
						C[i]=(byte)(two[i]^six[i]);
					}
					Four_Six_x[2]=C;
					if(five!=null){
						A = new byte [two.length];
						for (int i =0;i<C.length;i++)
						{
							A[i]=(byte)(C[i]^five[i]);
						}
						Four_Six_x[0]=A;
					}
					else{
						if(!decodedA)
							Four_Six_x[0]=null;
						else{}
					}
				}
				else{
					if(!decodedC)
						Four_Six_x[2]=null;
					{}
				}

			}
			else if (three !=null){
				Four_Six_x[2]=three;
				if(six != null){
					B = new byte [three.length];
					for (int i =0;i<B.length;i++)
					{
						B[i]=(byte)(three[i]^six[i]);
					}
					decodedB=true;
					Four_Six_x[1]=B;
					if(four!=null){
						A = new byte [three.length];
						for (int i =0;i<C.length;i++)
						{
							A[i]=(byte)(B[i]^four[i]);
						}
						decodedA = true;
						Four_Six_x[0]=A;
					}
					else{
						Four_Six_x[0]=null;
					}

				}
				else{
					Four_Six_x[1]=null;
				}
				if(five != null){
					A = new byte [three.length];
					for (int i =0;i<A.length;i++)
					{
						A[i]=(byte)(three[i]^five[i]);
					}
					Four_Six_x[0]=A;
					if(four!=null){
						B = new byte [three.length];
						for (int i =0;i<C.length;i++)
						{
							B[i]=(byte)(A[i]^four[i]);
						}
						Four_Six_x[1]=A;
					}
					else{
						if (!decodedB)
							Four_Six_x[1]=null;
						else{}
					}
				}
				else{
					if(!decodedA)
						Four_Six_x[0]=null;
					else{}
				}
			}
			return Four_Six_x;

		}
	}
}






